defmodule IocpMonitor.Worker.Supervisor do
  @moduledoc """
  电流盒子TCP连接工作进程的监护进程定义模块。
  本模块会为每个电流盒子的TCP连接创建一个独立的监护进程，
  并在此进程下创建多个工作进程，包括

    * 一个上行TCP包接收进程（`IocpMonitor.Worker.Receiver`）
    * 一个定时对时进程（`IocpMonitor.Worker.TimeAdjustment`）
    * 一个定时获取实时数据的进程（`IocpMonitor.Worker.RealtimeDataFetching`）。

  所有工作进程都是暂时（temporary）的，这意味着它们一旦退出，无论正常与否都不会重启。
  监护进程在任意工作进程退出时强制杀死其余所有被监护的工作进程，然后自己退出运行。
  """

  use Supervisor
  use IocpMonitor.Types

  alias IocpMonitor.Worker.{DeviceAddressHolder, Receiver, TimeAdjustment, RealtimeDataFetching, DataBuffer}

  @doc """
  启动监护进程
  """
  @spec start_link(tcp_client()) :: :ok | {:error, term()}
  def start_link(client) do
    # device_address = fetch_device_address(client)
    Supervisor.start_link(__MODULE__, client)
  end

  @impl true
  def init(client) do
    me = :erlang.pid_to_list(self())
    children = [
      {DeviceAddressHolder, {client, me}},
      {DataBuffer, {client, me}},
      {Receiver, {client, me}},
      {TimeAdjustment, {client, me}},
      {RealtimeDataFetching, {client, me}}
    ]

    Supervisor.init(children, strategy: :one_for_all)
  end

  # defp fetch_device_address(client) do
  #   :ok = Sender.device_address!(client)
  #   Receiver.receive_device_address(client)
  # end

  @doc false
  def child_spec(arg) do
    %{
      id: __MODULE__,
      start: {__MODULE__, :start_link, [arg]},
      type: :supervisor,
      restart: :temporary,
      shutdown: :infinity
    }
  end
end
